<template>
    <div class="grid_container">
        <n-steps vertical :current="current">
            <n-step v-for="item in process" :key="item.id" :title="item.title">
                <template #title>
                    <p class="step_title">
                        <span class="step_team--text" :class="item.excutor">{{ item.excutorTeam }}</span>
                        <span class="step_title--text">{{ item.title }}</span>
                    </p>
                </template>
                <div class="select_wrap" v-if="item.componentType === 'select'">
                    <n-select filterable :disabled="current !== item.taskSeniar"
                        v-for="(modelValue, selectIndex) in item.bindKey" v-model:value="bpAll[modelValue as BPKeyMaps]"
                        :render-label="(option: SelectOption) => renderLabel(option, item.optionsKey)"
                        :options="renderSelectOptions(item.optionsKey)" @update:value="sendPictureToFrontEnd(
                            $event,
                            modelValue as BPKeyMaps,
                            item.optionsKey
                        )" :placeholder="item.placeholder[selectIndex]">
                    </n-select>
                </div>
                <!-- 求生天赋选择 -->
                <TalentChoose ref="talentChooseRef" v-else-if="item.componentType === 'talent-sur'" :teamInfo
                    :survivorTeamKey="gameInfo.survivorTeam" :bpAll="bpAll" :canOperation="current === item.taskSeniar"
                    @change-side="toggleCharWithOthers" />
                <!-- 监管天赋选择 -->
                <HunterTalentChoose ref="talentChooseRef" v-else-if="item.componentType === 'talent-hun'" :teamInfo
                    :hunter-team-key="gameInfo.hunterTeam" :canOperation="current === item.taskSeniar" :bpAll="bpAll" />
                <n-button-group v-show="current === item.taskSeniar">
                    <!-- 下拉框下一步按钮 -->
                    <n-button @click="handlePreOrNext('next', item.bindKey, item.isInGlobalBan, item.excutor)"
                        v-if="item.componentType === 'select'">
                        <template #icon>
                            <n-icon>
                                <ArrowDownOutline />
                            </n-icon>
                        </template>
                        {{ $t('button.nextStep') }}
                    </n-button>
                    <!-- 天赋选择下一步按钮 -->
                    <n-button v-else @click="validateSave(item.componentType)">
                        <template #icon>
                            <n-icon>
                                <Archive />
                            </n-icon>
                        </template>
                        {{ $t('button.nextStep') }}
                    </n-button>
                    <n-button @click="switchCountDownControl">
                        <template #icon>
                            <n-icon>
                                <Alarm />
                            </n-icon>
                        </template>
                        {{ resetCountDown ? $t('button.closeResetCountDown') : $t('button.resetCountDown') }}
                    </n-button>
                    <n-button ghost @click="handlePreOrNext('pre')" v-if="current !== 1">
                        <template #icon>
                            <n-icon>
                                <ArrowUpSharp />
                            </n-icon>
                        </template>
                        {{ $t('button.lastStep') }}
                    </n-button>
                </n-button-group>
                <CountDownProcess v-if="current === item.taskSeniar" ref="countDownProcessRef" />
            </n-step>
        </n-steps>
        <!-- 比分结算面板 " -->
        <div class="task_score_wrap" v-show="current > process.length">
            <n-radio-group v-model:value="score" name="radiobuttongroup2" size="medium">
                <n-radio-button :value="{ survivor: 5, hunter: 0 }">
                    5 : 0(四跑)
                </n-radio-button>
                <n-radio-button :value="{ survivor: 3, hunter: 1 }">
                    3 : 1(三跑)
                </n-radio-button>
                <n-radio-button :value="{ survivor: 2, hunter: 2 }">
                    2 : 2(平局)
                </n-radio-button>
                <n-radio-button :value="{ survivor: 1, hunter: 3 }">
                    1 : 3(三抓)
                </n-radio-button>
                <n-radio-button :value="{ survivor: 0, hunter: 5 }">
                    0 : 5(四抓)
                </n-radio-button>
            </n-radio-group>
            <div class="grid_score">
                <div class="team_wrap">
                    ({{ $t('label.survivorTeam') }})
                    <img :src="teamInfo[gameInfo.survivorTeam]!.logo" />
                    <p>{{ teamInfo[gameInfo.survivorTeam]!.teamName }}</p>
                </div>
                <p class="score_middle">{{ score.survivor }} : {{ score.hunter }}</p>
                <div class="team_wrap">
                    <p>{{ teamInfo[gameInfo.hunterTeam]!.teamName }}</p>
                    <img :src="teamInfo[gameInfo.hunterTeam]!.logo" />
                    ({{ $t('label.hunterTeam') }})
                </div>
            </div>
            <n-button @click="handleEmiterScore" strong secondary round type="error">
                <template #icon>
                    <n-icon>
                        <CloudUpload />
                    </n-icon>
                </template>
                {{ $t('button.overScore') }}
            </n-button>
        </div>
    </div>
</template>
<script setup lang="ts">
import { ArrowDownOutline, ArrowUpSharp, Alarm, Archive, CloudUpload } from '@vicons/ionicons5';
import { ProcessInterface } from './generator';
import { hunOptions, surOptions } from '@/utils/generateImageOptions';
import BoardChannel from '@/utils/boardChannel';
import i18n from '@/lang';
import { useGameStore } from '@/stores/game';
import { useMessage, useDialog, SelectOption, NIcon } from 'naive-ui';
import CountDownProcess from '@/components/CountDownProcess.vue';
import TalentChoose from './TalentChoose.vue';
import HunterTalentChoose from './HunterTalentChoose.vue';
import { VNodeChild } from 'vue';
const { t } = i18n.global;
type TalentChooseInstance = InstanceType<typeof TalentChoose>;
type BPKeyMaps = keyof typeof bpAll;
const channel = new BoardChannel('bp-system');
const countDownProcessRef = ref(null);
const talentChooseRef = ref<TalentChooseInstance | null>(null);
const message = useMessage();
const dialog = useDialog();
const gameStore = useGameStore();
const props = defineProps<{
    'process': ProcessInterface[],
    'gameInfo': GameInfo,
    'teamInfo': Partial<TeamInfo>
}>();
const emits = defineEmits<{
    (event: 'emitScore', scoreInfo: GlobalScoreEmit): void
}
>();
const selectOptionsMap = {
    'surHalf': surOptions,
    'hunHalf': hunOptions
};
const resetCountDown = ref(true); //是否需要重置倒计时
// 计算options
const renderSelectOptions = (key: keyof typeof selectOptionsMap) => {
    return selectOptionsMap[key].map(item => {
        return {
            ...item,
            disabled: hasSelectChar[key].has(item.label)
        }
    });
}
// 步骤
const current = ref<number>(1);
// 全局bp选择
const globalResult: GloablBanComputed = {
    survivorBan: [],
    hunterBan: [],
}
const score = ref<ScoreComputed>({
    survivor: 0,
    hunter: 0
});
const hasSelectChar = reactive<Record<keyof typeof selectOptionsMap, Set<String>>>({
    surHalf: new Set(),
    hunHalf: new Set()
});
// 添加一个Map来跟踪每个key之前选择的值
const previousSelections = new Map<BPKeyMaps, string>();
const bpAll = reactive({
    banSur1: null,
    banSur2: null,
    banSur3: null,
    banSur4: null,
    pickSur1: null,
    pickSur2: null,
    pickSur3: null,
    pickSur4: null,
    banHun1: null,
    banHun2: null,
    banHun3: null,
    pickHun: null
});
// 发送选择角色到前台
const sendPictureToFrontEnd = (
    path: string,
    key: BPKeyMaps,
    filePath: 'hunHalf' | 'surHalf'
) => {
    // 获取角色选取禁用的key，增添进全局BP --设计缺陷：globalBan不能为字符串，应该为布尔值
    const previousValue = previousSelections.get(key);
    if (previousValue) {
        hasSelectChar[filePath].delete(previousValue);
    }

    // 添加新值到Set
    hasSelectChar[filePath].add(path);
    // 更新记录的上次选择
    previousSelections.set(key, path);
    channel.send('bpCharChange', {
        filePath,
        path,
        key
    })
};
// 发送比分
const handleEmiterScore = () => {
    if (score.value.survivor === 0 && score.value.hunter === 0) {
        return message.error('请先选择比分结果！');
    }
    dialog.warning({
        title: '警告',
        content: `
        您确定${props.teamInfo[props.gameInfo.survivorTeam]!.teamName} 
        对战 ${props.teamInfo[props.gameInfo.hunterTeam]!.teamName}的比分为
        ${score.value.survivor} : ${score.value.hunter}?一旦确认将不能修改本轮比分，请慎重检查再确认！`,
        positiveText: '确定',
        negativeText: '不确定',
        draggable: true,
        onPositiveClick: () => {
            emits('emitScore', {
                ...score.value,
                ...globalResult
            });
        },
        onNegativeClick: () => {
            message.error('不确定')
        }
    })

}
// 下一轮
const handlePreOrNext = (type: 'pre' | 'next', bindKey?: string[], isInGlobalBan?: boolean, excutor?: 'hunter' | 'survivor') => {
    let flag = true;//校验通过！
    if (bindKey && Array.isArray(bindKey)) {
        for (let i = 0; i < bindKey!.length; i++) {
            if (!previousSelections.get(bindKey[i] as BPKeyMaps)) {
                flag = false;
                break;
            }
        }
    };
    if (!flag) return message.error(t('text.fillThisTerm'));
    if (type === 'pre') {
        current.value--;
    } else {
        current.value++;
        const nowStep = props.process.find(item => item.taskSeniar === current.value);
        const transitionAnimtionString = nowStep?.showWaitAnimation ? JSON.stringify(nowStep.showWaitAnimation) : false;
        if (isInGlobalBan) {
            handleGlobalSave(bindKey!, excutor!); //处理全局比例
        }
        channel.send('showWaitAnimtion', transitionAnimtionString);
        if (!resetCountDown.value) return;
        resetTimeOut();
    }
};
// 处理全局bp
const handleGlobalSave = (bindKey: string[], excutor: 'hunter' | 'survivor') => {
    for (const key of bindKey) {
        const isExist = globalResult[`${excutor}Ban`].findIndex(item => item === bpAll[key as BPKeyMaps]) !== -1;
        if (!isExist) {
            globalResult[`${excutor}Ban`].push(bpAll[key as BPKeyMaps]!)
        }
    }
}
const switchCountDownControl = () => {
    resetCountDown.value = !resetCountDown.value;
}
// 重置倒计时
const resetTimeOut = () => {
    channel.send('resetTime', true);
    message.success(t('message.resetTime'));
};
// 初始化函数
const _init = () => {
    //  全局bp重新赋值
    const survivorBanSet = gameStore.gameInfo[props.gameInfo.survivorTeam].survivorGlobalBan;
    const hunterBanSet = gameStore.gameInfo[props.gameInfo.hunterTeam].hunterGlobalBan;
    survivorBanSet.forEach(item => {
        hasSelectChar.surHalf.add(item);
    });
    hunterBanSet.forEach(item => {
        hasSelectChar.hunHalf.add(item);
    });
    channel.send('globalBpChange', {
        survivorBans: Array.from(survivorBanSet),
        hunterBans: Array.from(hunterBanSet)
    });
    // 初始化的时候也检测一下是否有动画
    const nowStep = props.process.find(item => item.taskSeniar === current.value);
    const transitionAnimtionString = nowStep?.showWaitAnimation ? JSON.stringify(nowStep.showWaitAnimation) : false;
    channel.send('showWaitAnimtion', transitionAnimtionString);
}
_init();
// 交换角色
const toggleCharWithOthers = (nowIndex: number, toggleIndex: number) => {
    let result = bpAll[`pickSur${toggleIndex}` as BPKeyMaps]
    bpAll[`pickSur${toggleIndex}` as BPKeyMaps] = bpAll[`pickSur${nowIndex + 1}` as BPKeyMaps];
    bpAll[`pickSur${nowIndex + 1}` as BPKeyMaps] = result;
    // 注意nowIndex 是数组下标，toggleIndex 是交换的次数（非下标，即 下标 + 1）
    channel.send('toggleSur', {
        nowIndex,
        toggleIndex
    })
};
// 校验求生
const validateSave = async (componentType: string) => {
    if (talentChooseRef.value && Array.isArray(talentChooseRef.value)) {
        // 求生天赋选择
        if (componentType === 'talent-sur') {
            await talentChooseRef.value[0].postSurTalentMessage();
        }
        if (componentType === 'talent-hun') {
            await talentChooseRef.value[1].postHunTalentMessage();
        }
        channel.send('updateTalent', componentType);
        current.value++;
    };

}
// 渲染标签
const renderLabel = (option: SelectOption, selectOptionsKey: 'surHalf' | 'hunHalf'): VNodeChild => {
    const imageUrl = new URL(`../../assets/images/${selectOptionsKey}/${option.value}.png`, import.meta.url).href;
    return [
        h('img', {
            src: imageUrl,
            style: {
                width: '20px', // Adjust size as needed
                height: '20px', // Adjust size as needed
                verticalAlign: 'middle',
                marginRight: '8px',
                filter: option.disabled ? 'grayscale(100%)' : 'none',
                objectFit: 'cover', // 裁剪图片，保持比例，填充整个容器
                objectPosition: 'center', // 居中裁剪
            }
        }),
        option.label as string
    ]
}
</script>
<style scoped lang='scss'>
.select_wrap {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1em;
    margin-bottom: 1em;
}

.task_score_wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 6px;

    .grid_score {
        display: grid;
        grid-template-columns: auto 150px auto;
        align-items: center;
        margin: 1.5em 0;

        .score_middle {
            text-align: center;
            font-weight: bolder;
            color: #4090EF;
            font-size: 1.1rem;
        }

        .team_wrap {
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5em;

            img {
                width: 30px;
                height: 30px;
                border-radius: 50%;
                border: 2px solid #979797;
            }

            p {
                font-weight: bold;
            }
        }
    }
}

.step_title {
    font-size: 0.9em;
    font-weight: 500;

    .step_team--text {

        margin-right: 0.5em;

        &.survivor {
            color: #4090EF;
        }

        &.hunter {
            color: #F56C6C;
        }
    }

    .step_title--text {
        font-weight: 500;
        color: #333;
    }
}
</style>